﻿
#include "Defines.hpp"
#include "TheApp.hpp"
#pragma once
class MasterClient
{
public:
	MasterClient();
	~MasterClient();

	bool initialize(/*int argc, char* argv[]*/);
	void onTimer(int ms);
	void close();
	bool isRunning();
	bool cmdOptionExists(const std::string &option);
	const std::string& getCmdOption(const std::string &option);

public:
	void onConnected();
	void onDisconnected();
	void onMessage(cybertron::Message& msg);

public:
	//send:
	//Master::ENodeRegisterAtMaster
	//Master::ESyncWorkNodeStatusFromAgent
	//Master::ESyncWorkNodeStateFromAgent
	//Master::ESyncWorkNodeListFromAgent
	//Master::EStopTaskFromAgent
	//Master::ECommand2AgentFromRetCommander  还没写
	void Send2MasterRegister(Master::MasterNodeType tpye, string version, string desc, string data);
	void Send2MasterWorkNodeStartRetFromCommander(string taskId, string workNodeId,Common::EWorkNodeType workType, Common::ESimOneErrorCode errorCode, string message);
	void Send2MasterTaskStartRetFromCommander(string taskId, Common::ESimOneErrorCode errorCode,string message);
	void Send2MasterSyncWorkNodeStatus(string taskId, string workNodeId, Common::EWorkNodeType workType, Common::EWorkNodeStatus workStatus);
	void Send2MasterSyncWorkNodeState(string taskId, string workNodeId, Common::EWorkNodeType workType, Common::EWorkNodeState workStatus);
	void Send2MasterSyncWorkNodeList(WorkNodeInfoList& workNodeList);
	void Send2MasterSyncScalableNodeInfo(string workId, string workname, Common::EWorkNodeType workType);

	void Send2MasterStopTask(string from,string taskId, string workNodeId, Common::EWorkNodeType workType, Common::ETaskEndReason reason);

	void Send2MasterSycnWorkNodeDynamicConfig(Common::SyncWorkNodeDynamicConfig* pConfig);

	void Send2MasterCommanderRet(Master::SubCommandHeader header, const char *pBuffer, int length);
	std::shared_ptr<DaemonProcessContainer> mProcess;
private:
	void killZombieProcess();

	//newer
		//recv

	void onFromMasterNodeRegisterRet(cybertron::Message& msg);
	void onFromMasterCommand2Agent(cybertron::Message& msg);
	void onFromMasterGetAgentHardwareInfo(cybertron::Message& msg);
	void processCommandToAgent(cybertron::Message& msg);
	void processCommandToWork(cybertron::Message& msg);
	void onFromMasterTaskReadyRunning(cybertron::Message& msg);
	void onFromMasterStartTask(cybertron::Message& msg);
	void onFromMasterStopTask(cybertron::Message& msg);
	void onFromMasterStartWorkNode(cybertron::Message& msg);
	
	void onFromTaskStateChange(cybertron::Message& msg);
	void onFromMasterStopWorkNode(cybertron::Message& msg);
	void onFromMasterSyncWorkNodeDynamicConfig(cybertron::Message& msg);
	void onFromMasterStartScript(cybertron::Message& msg);
	void onFromMasterGetDongleInfo(cybertron::Message& msg);

	void onSubCommandPauseToWorkNode(std::string workNodeId);
	void onSubCommandPlayWorkNode(std::string workNodeId);
private:
	void zeroMembers();
	void reconnect();

	enum {
		ReconnectSeconds = 5, 
		CoordinatorTimeoutSeconds = 5, 
	};

private:
	// 
	void OnTimerMonitor(int ms);
private:
	cybertron::SocketTcpClientPtr mpSocketToMasterClient;
	std::shared_ptr<DaemonConfig> mpConfig;

	std::shared_ptr<ComputerEnv> mComputerEnv;
	std::string mMasterIp;
	int mMasterPort;
	int mReconnectCooldown;
	bool mForceToCoordinatorIp;
	//cybertron::NetworkActionExecuter mActionExecuter;
	cybertron::MessageRouter mMessageRouter;

	bool mbRunning;

private:
	std::vector <std::string> mOptions;
};
